package tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import src.CD;
import src.Item;
import src.Library;

public class TestLibraryItemHandling {

	private Library objectOfClassUnderTest;

	private Item item;

	@Before
	public void setUp() throws Exception {
		objectOfClassUnderTest = Library.getTheLibrary();

		item = new CD("title", "authorh", "01.01.1978");
	}

	@After
	public void tearDown() throws Exception {
		objectOfClassUnderTest = null;

		item = null;

		System.gc();
	}

	@Test
	public void testAddItem() throws Exception {

		assertTrue(
				"Libraries addItem method should return true if a new item was successfully added to the library!",
				objectOfClassUnderTest.addItem(item));
		assertTrue("A added item should be found at the library",
				objectOfClassUnderTest.inventory.contains(item));
	}

	@Test
	public void testAddItemWithNullArgument() throws Exception {
		try {
			objectOfClassUnderTest.addItem(null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}
	}

	@Test
	public void testGetItemSuccessful() throws Exception {
		this.objectOfClassUnderTest.addItem(item);
		assertEquals(
				"Libraries getItem method should return the item with the given name!",
				item, objectOfClassUnderTest.getItem("title"));

	}

	@Test
	public void testGetItemUnsuccessful() throws Exception {
		assertNull(
				"Libraries getItem method should return null if the item is no valid location!",
				objectOfClassUnderTest.getItem("somenotcontaineditem"));
	}

	@Test
	public void testGetItemWithNullArgument() throws Exception {
		try {
			objectOfClassUnderTest.getItem(null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}
	}

	// Bug: Can be only considered for Sets
	/**
	 * @Test public void testRemoveItemSuccessful() throws Exception {
	 *       objectOfClassUnderTest.addItem(item); //changed way of testing.
	 * 
	 *       assertTrue("Libraries removeItem method should return true if its argument was successful removed"
	 *       , objectOfClassUnderTest.removeItem(item));
	 *       assertFalse("A removed item should not be found at the library.",
	 *       objectOfClassUnderTest.inventory.contains(item)); }
	 **/

	@Test
	public void testRemoveItemUnsuccessful() throws Exception {
		assertFalse(
				"Libraries removeItem method should return false if its argument is no valid item!",
				this.objectOfClassUnderTest.removeItem(new CD("someNewTitle",
						"someAuthor", "01.01.1978")));
	}

	@Test
	public void testRemoveItemWithNullArgument() throws Exception {
		try {
			objectOfClassUnderTest.removeItem(null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}
	}
}
